import fs from 'fs';
import libopusPackage from 'libopus.js';

// 等待模块初始化
async function waitForModuleReady() {
    return new Promise((resolve, reject) => {
        console.log('等待libopus模块初始化...');
        let mod = libopusPackage;
        resolve(mod);
    });
}

// 测试OPUS解码
async function testOpusDecode(filePath) {
    try {
        console.log(`\n=== 测试OPUS解码: ${filePath} ===`);
        const data = fs.readFileSync(filePath);
        
        // 检查文件头
        if (data.length < 25) {
            console.log('❌ 文件太小');
            return;
        }
        
        const opusHead = data.slice(0, 8).toString('ascii');
        if (opusHead !== 'OpusHead') {
            console.log('❌ 不是有效的OPUS文件头');
            return;
        }
        
        // 解析文件头信息
        const version = data[8];
        const channels = data[9];
        const preSkip = data.readUInt16LE(10);
        const sampleRate = data.readUInt32LE(12);
        const outputGain = data.readUInt16LE(16);
        const channelMapping = data[18];
        const frameSize = data.readUInt16LE(19);
        const totalFrames = data.readUInt32LE(21);
        
        console.log(`采样率: ${sampleRate}Hz`);
        console.log(`通道数: ${channels}`);
        console.log(`帧大小: ${frameSize} 样本`);
        console.log(`总帧数: ${totalFrames}`);
        
        // 初始化OPUS解码器
        const libopus = await waitForModuleReady();
        const opusDecoder = libopus.OpusDecoder.create(sampleRate, channels);
        
        console.log('✅ OPUS解码器初始化成功');
        
        // 读取前几个OPUS帧进行解码测试
        let offset = 25;
        const framesToTest = Math.min(3, totalFrames);
        let totalDecodedSamples = 0;
        
        console.log(`\n=== 解码测试前 ${framesToTest} 个OPUS帧 ===`);
        for (let i = 0; i < framesToTest; i++) {
            if (offset + 4 > data.length) break;
            
            const frameLength = data.readUInt32LE(offset);
            offset += 4;
            
            if (offset + frameLength > data.length) break;
            
            const frameData = data.slice(offset, offset + frameLength);
            
            // 解析TOC字节
            const toc = frameData[0];
            const config = (toc >> 3) & 0x1F;
            const stereo = (toc >> 2) & 0x01;
            const frameType = toc & 0x3;
            
            console.log(`\n帧 ${i + 1}: ${frameData.length} 字节 (config: ${config}, frameType: ${frameType})`);
            
            try {
                // 解码OPUS帧
                const decodedData = opusDecoder.decode(frameData);
                
                if (decodedData && decodedData.length > 0) {
                    console.log(`✅ 解码成功: ${decodedData.length} 样本`);
                    totalDecodedSamples += decodedData.length;
                    
                    // 检查解码后的数据
                    const samples = new Int16Array(decodedData.buffer, decodedData.byteOffset, decodedData.length / 2);
                    const maxSample = Math.max(...samples);
                    const minSample = Math.min(...samples);
                    const avgSample = samples.reduce((sum, val) => sum + Math.abs(val), 0) / samples.length;
                    
                    console.log(`  最大样本值: ${maxSample}`);
                    console.log(`  最小样本值: ${minSample}`);
                    console.log(`  平均绝对值: ${avgSample.toFixed(2)}`);
                    
                    if (avgSample < 10) {
                        console.log(`⚠️  警告: 平均样本值很低，可能是静音或无效数据`);
                    }
                } else {
                    console.log(`❌ 解码失败: 返回空数据`);
                }
            } catch (error) {
                console.log(`❌ 解码错误: ${error.message}`);
            }
            
            offset += frameLength;
        }
        
        console.log(`\n=== 解码测试完成 ===`);
        console.log(`总解码样本数: ${totalDecodedSamples}`);
        console.log(`预期样本数: ${framesToTest * frameSize}`);
        
        if (totalDecodedSamples === framesToTest * frameSize) {
            console.log('✅ 解码样本数正确');
        } else {
            console.log('❌ 解码样本数不匹配');
        }
        
    } catch (error) {
        console.error('测试失败:', error.message);
    }
}

// 主函数
async function main() {
    const args = process.argv.slice(2);
    
    if (args.length === 0) {
        console.log('用法: node test_opus_decode.js <opus文件路径>');
        return;
    }
    
    const filePath = args[0];
    if (!fs.existsSync(filePath)) {
        console.log('文件不存在:', filePath);
        return;
    }
    
    await testOpusDecode(filePath);
}

main();
